#ifndef CONDIMENTDECORATOR_HPP
#define CONDIMENTDECORATOR_HPP

#include "Beverage.hpp"

class CondimentDecorator : public Beverage
{
protected:
  Beverage *_object;

public:
  CondimentDecorator()
      : _object(nullptr)
  {
  }

  CondimentDecorator(std::string description, double cost)
      : _object(nullptr), Beverage(description, cost)
  {
  }
};

class Milk : public CondimentDecorator
{
private:
  Beverage *_object;

public:
  Milk()
      : _object(nullptr), CondimentDecorator("牛奶", 5)
  {
  }

  Milk(Beverage *obj)
      : _object(obj), CondimentDecorator("牛奶", 5)
  {
  }

  std::string GetDescription()
  {
    if (_object != nullptr)
      std::cout << _object->GetDescription() << " + ";
    return _description;
  }

  double Cost()
  {
    return _cost + _object->Cost();
  }
};

class Soy : public CondimentDecorator
{
protected:
  Beverage *_object;

public:
  Soy()
      : _object(nullptr), CondimentDecorator("豆浆", 3)
  {
  }

  Soy(Beverage *obj)
      : _object(obj), CondimentDecorator("豆浆", 3)
  {
  }

  std::string GetDescription()
  {
    if (_object != nullptr)
      std::cout << _object->GetDescription() << " + ";
    return _description;
  }

  double Cost()
  {
    return _cost + _object->Cost();
  }
};

class Mocha : public CondimentDecorator
{
protected:
  Beverage *_object;

public:
  Mocha()
      : _object(nullptr), CondimentDecorator("抹茶", 8)
  {
  }

  Mocha(Beverage *obj)
      : _object(obj), CondimentDecorator("抹茶", 8)
  {
  }

  std::string GetDescription()
  {
    if (_object != nullptr)
      std::cout << _object->GetDescription() << " + ";
    return _description;
  }

  double Cost()
  {
    return _cost + _object->Cost();
  }
};

class Chocolate : public CondimentDecorator
{
protected:
  Beverage *_object;

public:
  Chocolate()
      : _object(nullptr), CondimentDecorator("巧克力", 10)
  {
  }

  Chocolate(Beverage *obj)
      : _object(obj), CondimentDecorator("巧克力", 10)
  {
  }

  std::string GetDescription()
  {
    if (_object != nullptr)
      std::cout << _object->GetDescription() << " + ";
    return _description;
  }

  double Cost()
  {
    return _cost + _object->Cost();
  }
};

class Whip : public CondimentDecorator
{
protected:
  Beverage *_object;

public:
  Whip()
      : _object(nullptr), CondimentDecorator("鲜奶油", 12)
  {
  }

  Whip(Beverage *obj)
      : _object(obj), CondimentDecorator("鲜奶油", 12)
  {
  }

  std::string GetDescription()
  {
    if (_object != nullptr)
      std::cout << _object->GetDescription() << " + ";
    return _description;
  }

  double Cost()
  {
    return _cost + _object->Cost();
  }
};
#endif
